using System;
using System.Collections.Generic;
using System.Linq;

namespace MySoftLab.DapFlash.Models
{
    public class IntelHexParser
    {
        private const int EXTENDED_LINEAR_ADDRESS_RECORD = 0x04;
        private const int DATA_RECORD = 0x00;
        private const int END_OF_FILE_RECORD = 0x01;

        public (uint StartAddress, byte[] Data) ParseHexFile(string[] hexLines)
        {
            var memoryBlocks = new SortedDictionary<uint, byte>();
            uint baseAddress = 0;
            uint? firstAddress = null;

            foreach (var line in hexLines)
            {
                if (!line.StartsWith(":")) continue;

                var hexLine = line.Substring(1); // 移除开头的":"
                var byteCount = Convert.ToByte(hexLine.Substring(0, 2), 16);
                var address = Convert.ToUInt16(hexLine.Substring(2, 4), 16);
                var recordType = Convert.ToByte(hexLine.Substring(6, 2), 16);
                var data = hexLine.Substring(8, byteCount * 2);

                switch (recordType)
                {
                    case EXTENDED_LINEAR_ADDRESS_RECORD:
                        baseAddress = Convert.ToUInt32(data, 16) << 16;
                        break;

                    case DATA_RECORD:
                        var fullAddress = baseAddress + address;
                        if (firstAddress == null)
                        {
                            firstAddress = fullAddress;
                        }

                        for (int i = 0; i < byteCount; i++)
                        {
                            var byteValue = Convert.ToByte(data.Substring(i * 2, 2), 16);
                            memoryBlocks[fullAddress + (uint)i] = byteValue;
                        }
                        break;

                    case END_OF_FILE_RECORD:
                        break;
                }
            }

            if (!memoryBlocks.Any())
            {
                throw new InvalidOperationException("HEX文件不包含有效数据");
            }

            // 获取连续的内存块
            uint startAddress = firstAddress ?? 0;
            uint endAddress = memoryBlocks.Keys.Max();
            var size = endAddress - startAddress + 1;
            var binaryData = new byte[size];

            foreach (var kvp in memoryBlocks)
            {
                var offset = kvp.Key - startAddress;
                binaryData[offset] = kvp.Value;
            }

            return (startAddress, binaryData);
        }
    }
} 